# -*- coding=utf8 -*-
from typing import Dict, Tuple

import redis

from configs.kb_config import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB


class RedisClient:
    _pool_dict: Dict[Tuple[str, int, int, str], redis.ConnectionPool] = {}

    def __init__(
        self,
        host: str = "localhost",
        port: int = 6379,
        db: int = 0,
        password: str = None,
        ssl: bool = False,
        decode_responses: bool = True,
        max_connections: int = 50,
    ):
        self.host = host
        self.port = port
        self.db = db
        self.password = password
        self.ssl = ssl
        self.decode_responses = decode_responses
        self.max_connections = max_connections

        pool_key = (host, port, db, password)
        if pool_key not in self._pool_dict:
            self._pool_dict[pool_key] = redis.ConnectionPool(
                host=host,
                port=port,
                db=db,
                password=password,
                decode_responses=decode_responses,
                max_connections=max_connections,
            )

        self._r = redis.Redis(connection_pool=self._pool_dict[pool_key])
        self._ping()

    def _ping(self):
        try:
            self._r.ping()
        except BaseException as e:
            raise e

    # ---------- 对外接口 ----------

    @property
    def redis_db_frame(self) -> redis.Redis:
        """直接返回单点连接（不走池）"""
        return redis.Redis(
            host=self.host,
            port=self.port,
            password=self.password,
            db=self.db,
            decode_responses=self.decode_responses,
            ssl=self.ssl,
        )

    @property
    def redis_db_pool(self) -> redis.Redis:
        """返回池化连接（推荐）"""
        return self._r

    @property
    def redis_pool(self) -> redis.ConnectionPool:
        """返回连接池对象"""
        return self._pool_dict[(self.host, self.port, self.db, self.password)]

    @property
    def redis_cluster_frame(self) -> redis.RedisCluster:
        """返回 RedisCluster 连接"""
        return redis.RedisCluster(
            host=self.host,
            port=self.port,
            password=self.password,
            decode_responses=self.decode_responses,
            ssl=self.ssl,
        )


# 单例化
redis_client = RedisClient(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PASSWORD)
redis_pool = redis_client.redis_db_pool
